﻿#include "CFMesh.h"
#include <chrono>
#include <iostream>
#include <stdlib.h>
#include <thread>

#include "vtkfmt/format.h"
#include "Geometry.h"
#include "easyloggingpp.h"
#include <QDebug>
//load .foam
#include "pqActiveObjects.h"
#include "pqLoadDataReaction.h"
#include "pqUndoStack.h"
#include "pqStandardRecentlyUsedResourceLoaderImplementation.h"
#include "pqObjectBuilder.h"
#include "vtkSMProxy.h"
#include "pqOutputWidget.h"
#include <QStringList>
#include"qmessagebox.h"

CFMesh::CFMesh(const Geometry& geometry)
  : Mesh(geometry)
{

}

CFMesh::~CFMesh() 
{

}

void CFMesh::Build()
{
  auto fileNameExtension = m_Geometry.GetFileName();
  auto fileName = m_Geometry.GetStem();
  std::string CreatBox = ("surfaceGenerateBoundingBox " + fileNameExtension + " " +
                          fileName + "_box" + ".stl" + m_BoundingBoxParameter)
                           .c_str();
  auto newfileNameExten = fileName + "_box" + ".stl";
  auto newfileName = fileName + "_box";
  std::string CreatFms =
    "surfaceFeatureEdges " + newfileNameExten + " " + newfileName + ".fms";
  std::string CreatFoam = "type nul>" + newfileName + ".foam";

  /*system(fmt::format(CreatBox, m_WorkSpace).c_str());
  system(fmt::format(CreatFms, m_WorkSpace).c_str());
  system(fmt::format(CreatFoam, m_WorkSpace).c_str());*/
  //system(fmt::format("cd {} && cartesianMesh", m_WorkSpace).c_str());

  m_generateMesh = new QProcess();

  m_generateMesh->setReadChannel(QProcess::StandardOutput);
  m_generateMesh->setWorkingDirectory(".\\workspace\\demo");

  m_generateMesh->start("cmd.exe");
  m_generateMesh->write("pangu::Start... \n");

  QObject::connect(m_generateMesh, SIGNAL(readyReadStandardOutput()), this, SLOT(onReadData()));
  QObject::connect(m_generateMesh, SIGNAL(finished(int)), this, SLOT(onOpenFOAM()));
  m_generateMesh->write(
    QString::fromStdString(
      fmt::format("{} && {} && {} && cartesianMesh && exit\r\n", CreatBox, CreatFms, CreatFoam))
      .toUtf8());
}

void CFMesh::onReadData()
{
  if (m_generateMesh)
  {
    QString msg = QString::fromLocal8Bit(m_generateMesh->readAllStandardOutput());
    QtMsgType type = QtInfoMsg;
    if (msg.contains("pangu::"))
    {
      int rate = 0;
      QString processMsg = "";
      if (msg.contains("Start..."))
      {
        emit writeProcessRate("Start", 0);
       
        processMsg = "Start Mesh";
        rate = 5;
      }
      else if (msg.contains("templateGeneration"))
      {
        processMsg = "Template Generation";
        rate = 10;
      }
      else if (msg.contains("surfaceTopology"))
      {
        processMsg = "Surface Topology";
        rate = 25;
      }
      else if (msg.contains("surfaceProjection"))
      {
        processMsg = "Surface Projection";
        rate = 40;
      }
      else if (msg.contains("patchAssignment"))
      {
        processMsg = "Patch Assignment";
        rate = 50;
      }
      else if (msg.contains("edgeExtraction"))
      {
        
        processMsg = "Edge Extraction";
        rate = 60;
      }
      else if (msg.contains("boundaryLayerGeneration"))
      {
        processMsg = "Boundary Layer Generation";
        rate = 75;
      }
      else if (msg.contains("meshOptimisation"))
      {
        processMsg = "Mesh Optimisation";
        rate = 90;
      }
      else if (msg.contains("boundaryLayerRefinement"))
      {
        processMsg = "Boundary Layer Refinement";
        rate = 95;
      }
      else if (msg.contains("Finished MeshWriting"))
      {
        processMsg = "Finished MeshWriting";
        rate = 100;
      }
      emit writeProcessRate(processMsg, rate);
    }
    
    QStringList strlist = msg.split("\n");
    for (int i = 0; i < strlist.size() - 1; i++)
    {
      if (strlist[i].contains("FOAM FATAL"))
      {
        type = QtFatalMsg;
      }
      else if (strlist[i].contains("FOAM Warning"))
      {
        type = QtWarningMsg;
      }
      Q_EMIT MessageHandler::handlerVTK(type, strlist[i]);
    }
      
  }
}

void CFMesh::onOpenFOAM()
{
  qDebug() << "finish!!!!!!!!!!!!!!";
  auto fileName = m_Geometry.GetStem() + "_box.foam";
  
  QString pltFile = QString::fromStdString(fmt::format(".\\workspace\\demo\\{}", fileName));
  if (!pltFile.isEmpty())
  {
    QList<QString> files;
    files.append(pltFile);
    pqServer* server = pqActiveObjects::instance().activeServer();
    QPair<QString, QString> readInfo = QPair<QString, QString>("OpenFOAMReader", "sources");
    //pqPipelineSource* reader1 = pqLoadDataReaction::LoadFileExportSTL(files, server, readInfo);

    if (files.empty())
    {
      return;
    }

    server = server != NULL ? server : pqActiveObjects::instance().activeServer();
    if (!server)
    {
      qCritical() << "Cannot create reader without an active server.";
      return;
    }
    BEGIN_UNDO_SET("Create 'Reader'");
    pqObjectBuilder* builder = pqApplicationCore::instance()->getObjectBuilder();
    pqPipelineSource* reader =
      builder->createReader(readInfo.second, readInfo.first, files, server);
    END_UNDO_SET();
    if (reader)
    {
      pqStandardRecentlyUsedResourceLoaderImplementation::addDataFilesToRecentResources(
        server, files, reader->getProxy()->GetXMLGroup(), reader->getProxy()->GetXMLName());
    }
  }
}
